import java.util.*;
import java.io.*;
import java.sql.*;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.sql.DataSource;

public class SimpleConnectionPoolDateSource implements DataSource {
    private Properties props;
    private String url;
    private String user;
    private String passwd;
    private int max;
    private List<Connection> conns;

    public SimpleConnectionPoolDateSource()
        throws IOException,ClassNotFoundException{
        this("jdbc.properties");
    }

    public SimpleConnectionPoolDateSource(String configFile)
        throws IOException,ClassNotFoundException{
        props=new Properties();
        props.load(new FileInputStream(configFile));

        url=props.getProperty("url");
        user=props.getProperty("user");
        passwd=props.getProperty("password");
        max=Integer.parseInt(props.getProperty("poolmax"));

        conns=Connections.synchronizedList(new ArrayList<Connection>());
    }

    public synchronized Connection getConnection() throws SQLException{
        if (conns.isEmpty()){
            return new ConnectionWrapper(
                    DriverManager.getConnection(url,user,passwd),conns,max
            );
        }
        else {
            return conns.remove(conns.size()-1);
        }
    }

    private class ConnectionWrapper implements Connection{
        private Connection conn;
        private List<Connection> conns;
        private int max;

        public ConnectionWrapper(Connection conn,List<Connection> conns,int max){

            this.conn=conn;
            this.conns=conns;
            this.max=max;
        }

        @Override
        public void close() throws SQLException{
            if (conns.size()==max){
                conn.close();
            }
            else {
                conns.add(this);
            }
        }

        @Override
        public Statement createStatement() throws SQLException{
            return conn.createStatement();
        }
        ...
    }
    ...
}